package models

import (
	"jlpay-sdk-go/pkg/jlpay/core"
)

// ==================== 提现查询 ====================

// WithdrawQueryRequest 提现查询请求
type WithdrawQueryRequest struct {
	OrgBaseRequest
	// OutSettleID 外部结算ID
	OutSettleID string `json:"out_settle_id,omitempty"`
	// 原始请求映射数据
	rawRequestMap map[string]interface{} `json:"-"`
}

// NewWithdrawQueryRequest 创建提现查询请求
func NewWithdrawQueryRequest() *WithdrawQueryRequest {
	req := &WithdrawQueryRequest{}
	return req
}

// SetOutSettleID 设置外部结算ID
func (r *WithdrawQueryRequest) SetOutSettleID(outSettleID string) *WithdrawQueryRequest {
	r.OutSettleID = outSettleID
	return r
}

// SetRawRequestMap 设置原始请求映射数据
func (r *WithdrawQueryRequest) SetRawRequestMap(rawMap map[string]interface{}) *WithdrawQueryRequest {
	r.rawRequestMap = rawMap
	return r
}

// GetRawMap 获取原始请求映射数据
func (r *WithdrawQueryRequest) GetRawMap() (map[string]interface{}, bool) {
	return r.rawRequestMap, len(r.rawRequestMap) > 0
}

// ToMap 转换为map
func (r *WithdrawQueryRequest) ToMap() (map[string]interface{}, error) {
	// 如果有原始请求数据，优先使用
	if rawMap, hasRaw := r.GetRawMap(); hasRaw {
		return rawMap, nil
	}

	// 先获取基类的map
	baseMap, err := r.OrgBaseRequest.ToMap()
	if err != nil {
		return nil, err
	}

	// 添加自己的字段
	if r.OutSettleID != "" {
		baseMap["out_settle_id"] = r.OutSettleID
	}

	return baseMap, nil
}

// CheckRequiredParams 检查必需参数
func (r *WithdrawQueryRequest) CheckRequiredParams(config *core.Config) error {
	// 与Python版本保持一致，不进行参数校验
	return nil
}

// WithdrawQueryResponse 提现查询响应
type WithdrawQueryResponse struct {
	StandardResponse
	// SettleType 结算类型
	SettleType string `json:"settle_type,omitempty"`
	// Amount 金额
	Amount string `json:"amount,omitempty"`
	// ResultState 结果状态
	ResultState string `json:"result_state,omitempty"`
	// PaymentTime 付款时间
	PaymentTime string `json:"payment_time,omitempty"`
	// SettleID 结算ID
	SettleID string `json:"settle_id,omitempty"`
	// OutSettleID 外部结算ID
	OutSettleID string `json:"out_settle_id,omitempty"`
	// FeeAmount 手续费
	FeeAmount string `json:"fee_amount,omitempty"`
	// Postscript 附言
	Postscript string `json:"postscript,omitempty"`
}

// NewWithdrawQueryResponse 创建提现查询响应
func NewWithdrawQueryResponse() *WithdrawQueryResponse {
	return &WithdrawQueryResponse{}
}

// ==================== 提现申请 ====================

// WithdrawApplyRequest 提现申请请求
type WithdrawApplyRequest struct {
	OrgBaseRequest
	// Amount 金额
	Amount string `json:"amount,omitempty"`
	// SettleType 结算类型
	SettleType string `json:"settle_type,omitempty"`
	// OutSettleID 外部结算ID
	OutSettleID string `json:"out_settle_id,omitempty"`
	// NotifyURL 通知地址
	NotifyURL string `json:"notify_url,omitempty"`
	// Postscript 附言
	Postscript string `json:"postscript,omitempty"`
	// 原始请求映射数据
	rawRequestMap map[string]interface{} `json:"-"`
}

// NewWithdrawApplyRequest 创建提现申请请求
func NewWithdrawApplyRequest() *WithdrawApplyRequest {
	req := &WithdrawApplyRequest{}
	return req
}

// SetAmount 设置金额
func (r *WithdrawApplyRequest) SetAmount(amount string) *WithdrawApplyRequest {
	r.Amount = amount
	return r
}

// SetSettleType 设置结算类型
func (r *WithdrawApplyRequest) SetSettleType(settleType string) *WithdrawApplyRequest {
	r.SettleType = settleType
	return r
}

// SetOutSettleID 设置外部结算ID
func (r *WithdrawApplyRequest) SetOutSettleID(outSettleID string) *WithdrawApplyRequest {
	r.OutSettleID = outSettleID
	return r
}

// SetNotifyURL 设置通知地址
func (r *WithdrawApplyRequest) SetNotifyURL(notifyURL string) *WithdrawApplyRequest {
	r.NotifyURL = notifyURL
	return r
}

// SetPostscript 设置附言
func (r *WithdrawApplyRequest) SetPostscript(postscript string) *WithdrawApplyRequest {
	r.Postscript = postscript
	return r
}

// SetRawRequestMap 设置原始请求映射数据
func (r *WithdrawApplyRequest) SetRawRequestMap(rawMap map[string]interface{}) *WithdrawApplyRequest {
	r.rawRequestMap = rawMap
	return r
}

// GetRawMap 获取原始请求映射数据
func (r *WithdrawApplyRequest) GetRawMap() (map[string]interface{}, bool) {
	return r.rawRequestMap, len(r.rawRequestMap) > 0
}

// ToMap 转换为map
func (r *WithdrawApplyRequest) ToMap() (map[string]interface{}, error) {
	// 如果有原始请求数据，优先使用
	if rawMap, hasRaw := r.GetRawMap(); hasRaw {
		return rawMap, nil
	}

	// 先获取基类的map
	baseMap, err := r.OrgBaseRequest.ToMap()
	if err != nil {
		return nil, err
	}

	// 添加自己的字段
	if r.Amount != "" {
		baseMap["amount"] = r.Amount
	}
	if r.SettleType != "" {
		baseMap["settle_type"] = r.SettleType
	}
	if r.OutSettleID != "" {
		baseMap["out_settle_id"] = r.OutSettleID
	}
	if r.NotifyURL != "" {
		baseMap["notify_url"] = r.NotifyURL
	}
	if r.Postscript != "" {
		baseMap["postscript"] = r.Postscript
	}

	return baseMap, nil
}

// CheckRequiredParams 检查必需参数
func (r *WithdrawApplyRequest) CheckRequiredParams(config *core.Config) error {
	// 与Python版本保持一致，不进行参数校验
	return nil
}

// WithdrawApplyResponse 提现申请响应
type WithdrawApplyResponse struct {
	StandardResponse
	// Amount 金额
	Amount string `json:"amount,omitempty"`
	// SettleType 结算类型
	SettleType string `json:"settle_type,omitempty"`
	// ResultState 结果状态
	ResultState string `json:"result_state,omitempty"`
	// ResultMsg 结果消息
	ResultMsg string `json:"result_msg,omitempty"`
	// SettleID 结算ID
	SettleID string `json:"settle_id,omitempty"`
	// OutSettleID 外部结算ID
	OutSettleID string `json:"out_settle_id,omitempty"`
	// FeeAmount 手续费
	FeeAmount string `json:"fee_amount,omitempty"`
}

// NewWithdrawApplyResponse 创建提现申请响应
func NewWithdrawApplyResponse() *WithdrawApplyResponse {
	return &WithdrawApplyResponse{}
}

// ==================== 结算资金查询 ====================

// AccBalanceRequest 结算资金查询请求
type AccBalanceRequest struct {
	OrgBaseRequest
	// AcctType 账户类型
	AcctType string `json:"acct_type,omitempty"`
	// 原始请求映射数据
	rawRequestMap map[string]interface{} `json:"-"`
}

// NewAccBalanceRequest 创建结算资金查询请求
func NewAccBalanceRequest() *AccBalanceRequest {
	req := &AccBalanceRequest{}
	return req
}

// SetAcctType 设置账户类型
func (r *AccBalanceRequest) SetAcctType(acctType string) *AccBalanceRequest {
	r.AcctType = acctType
	return r
}

// SetRawRequestMap 设置原始请求映射数据
func (r *AccBalanceRequest) SetRawRequestMap(rawMap map[string]interface{}) *AccBalanceRequest {
	r.rawRequestMap = rawMap
	return r
}

// GetRawMap 获取原始请求映射数据
func (r *AccBalanceRequest) GetRawMap() (map[string]interface{}, bool) {
	return r.rawRequestMap, len(r.rawRequestMap) > 0
}

// ToMap 转换为map
func (r *AccBalanceRequest) ToMap() (map[string]interface{}, error) {
	// 如果有原始请求数据，优先使用
	if rawMap, hasRaw := r.GetRawMap(); hasRaw {
		return rawMap, nil
	}

	// 先获取基类的map
	baseMap, err := r.OrgBaseRequest.ToMap()
	if err != nil {
		return nil, err
	}

	// 添加自己的字段
	if r.AcctType != "" {
		baseMap["acct_type"] = r.AcctType
	}

	return baseMap, nil
}

// CheckRequiredParams 检查必需参数
func (r *AccBalanceRequest) CheckRequiredParams(config *core.Config) error {
	// 与Python版本保持一致，不进行参数校验
	return nil
}

// AccBalanceResponse 结算资金查询响应
type AccBalanceResponse struct {
	StandardResponse
	// Balance 余额
	Balance string `json:"balance,omitempty"`
	// AvailableBalance 可用余额
	AvailableBalance string `json:"available_balance,omitempty"`
	// FrozenAmount 冻结金额
	FrozenAmount string `json:"frozen_amount,omitempty"`
	// Status 状态
	Status string `json:"status,omitempty"`
}

// NewAccBalanceResponse 创建结算资金查询响应
func NewAccBalanceResponse() *AccBalanceResponse {
	return &AccBalanceResponse{}
}

// ==================== 通知DTO ====================

// NotifyDto 通知数据传输对象
type NotifyDto struct {
	// MerchNo 商户号
	MerchNo string `json:"merch_no,omitempty"`
	// SettleType 结算类型
	SettleType string `json:"settle_type,omitempty"`
	// Amount 金额
	Amount string `json:"amount,omitempty"`
	// FeeAmount 手续费
	FeeAmount string `json:"fee_amount,omitempty"`
	// OutSettleID 外部结算ID
	OutSettleID string `json:"out_settle_id,omitempty"`
	// SettleID 结算ID
	SettleID string `json:"settle_id,omitempty"`
	// Postscript 附言
	Postscript string `json:"postscript,omitempty"`
	// PaymentTime 付款时间
	PaymentTime string `json:"payment_time,omitempty"`
	// OrgNo 机构号
	OrgNo string `json:"org_no,omitempty"`
	// ResultState 结果状态
	ResultState string `json:"result_state,omitempty"`
}

// NewNotifyDto 创建通知DTO
func NewNotifyDto(data map[string]interface{}) *NotifyDto {
	dto := &NotifyDto{}
	if data != nil {
		if merchNo, ok := data["merch_no"].(string); ok {
			dto.MerchNo = merchNo
		}
		if settleType, ok := data["settle_type"].(string); ok {
			dto.SettleType = settleType
		}
		if amount, ok := data["amount"].(string); ok {
			dto.Amount = amount
		}
		if feeAmount, ok := data["fee_amount"].(string); ok {
			dto.FeeAmount = feeAmount
		}
		if outSettleID, ok := data["out_settle_id"].(string); ok {
			dto.OutSettleID = outSettleID
		}
		if settleID, ok := data["settle_id"].(string); ok {
			dto.SettleID = settleID
		}
		if postscript, ok := data["postscript"].(string); ok {
			dto.Postscript = postscript
		}
		if paymentTime, ok := data["payment_time"].(string); ok {
			dto.PaymentTime = paymentTime
		}
		if orgNo, ok := data["org_no"].(string); ok {
			dto.OrgNo = orgNo
		}
		if resultState, ok := data["result_state"].(string); ok {
			dto.ResultState = resultState
		}
	}
	return dto
}
